package com.wdf.rule.drools;

import org.apache.commons.lang3.StringUtils;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author wangdingfu
 * @date 2023-11-16 20:25:57
 */
public class DynamicClassLoader extends ClassLoader {


    /**
     * 缓存源代码对象
     */
    private Map<String, CustomJavaFileObject> fileCacheMap = new ConcurrentHashMap<>(16);

    private Map<String, String> classPathMap = new ConcurrentHashMap<>();

    /**
     * 初始化类加载器
     *
     * @param parent
     */
    public DynamicClassLoader(ClassLoader parent) {
        super(parent);
    }

    /**
     * 添加源码缓存
     *
     * @param obj
     */
    public void addJavaCode(CustomJavaFileObject obj) {
        String name = obj.getName();
        fileCacheMap.put(name, obj);
        if (StringUtils.isNotBlank(name)) {
            String pathName = name.replace('.', File.separatorChar);
            classPathMap.put(pathName + ".class", name);
        }
    }

    @Override
    public InputStream getResourceAsStream(String name) {
        if (classPathMap.containsKey(name)) {
            String pkg = classPathMap.get(name);
            if (StringUtils.isNotBlank(pkg)) {
                byte[] byteCode = fileCacheMap.get(pkg).getByteCode();
                if (byteCode != null) {
                    return new ByteArrayInputStream(byteCode);
                }
            }
        }
        return super.getResourceAsStream(name);
    }


    @Override
    protected URL findResource(String name) {
        if (classPathMap.containsKey(name)) {
            String pkg = classPathMap.get(name);
            if (StringUtils.isNotBlank(pkg)) {
                byte[] byteCode = fileCacheMap.get(pkg).getByteCode();
                //重写获取class
            }
        }
        return super.findResource(name);
    }

    /**
     * 获取类
     *
     * @param className The <a href="#binary-name">binary name</a> of the class
     * @return
     * @throws ClassNotFoundException
     */
    @Override
    protected Class<?> findClass(String className) throws ClassNotFoundException {
        if (fileCacheMap.containsKey(className)) {
            byte[] byteCode = fileCacheMap.get(className).getByteCode();
            return defineClass(className, byteCode, 0, byteCode.length);
        } else {
            return super.findClass(className);
        }
    }
}
